書接昨日,在 MIDI 裡面有固定的格式在記錄聲音的訊號,因為實在是太多了我們不會一一舉例,這邊只說明幾個常用到的,完整的官方文件請參照這裡
1.Program change
用於更改不同 channel 的樂器音色
Message('program_change',channel,id,time =0)
Note on
音符的開始
Message('note_on',note,vel,time,channel)
Note off
音符的結束,通常緊跟在 Note on 後面
Message('note_off',note,vel,time,channel)
Control change (cc)
控制聲音,比方說踩鋼琴的延音踏板這類的操作
Message('control_change',channel,control,value,time)
control 可以選擇要對聲音做哪些奇妙操作,詳細請參考這篇,這裡列幾個常用到的操作
value 則是控制實際操作的程度,比方說踩延音踏版這件事在 value =< 63 是 off 反之則是 on
我們試著來編追追追 ~
from mido import Message, MidiFile, MidiTrack
mid = MidiFile()
track = MidiTrack()
def play_part(track, note, len_ ,note_bias=0,vel=1.0,delay=0,change=False,double=False):
# 每個節拍的時間長度
temple = 60*60*10/75
# 大調,參考別人的做法的,我也不是很懂樂理
major_notes = [0,2,2,1,2,2,2,1]
# C4 - 正中間的 DO
base_note = 60
bias = note_bias*12 + sum(major_notes[0:note])
vel = round(64*vel)
t_start = round(delay*temple)
t_end = round(temple*len_)
if not double:
track.append(Message("note_on", note=base_note+bias,velocity=vel,time=t_start))
track.append(Message("note_off", note=base_note+bias,velocity=vel,time=t_end))
if change:
track.append(Message("control_change",channel=0,control=64,value=64,time=t_start))
track.append(Message("control_change",channel=0,control=64,value=0,time=t_end))
if double:
track.append(Message("program_change", channel=1,program=41 ,time = t_start))
track.append(Message("note_on",channel=1, note=base_note+bias,velocity=vel,time = t_start))
track.append(Message("note_off",channel=1, note=base_note+bias,velocity=vel,time = t_end))
track.append(Message("program_change", channel=1,program=0 ,time=t_end))
return track
track = play_part(track,6,0.5)
######## 第一段 ###########
track = play_part(track,5,0.5)
track = play_part(track,6,0.5)
track = play_part(track,6,0.5)
track = play_part(track,5,0.5)
track = play_part(track,3,0.5)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)
track = play_part(track,3,1.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)
track = play_part(track,3,1.0,change=True)
track = play_part(track,3,0.25,double=True)
track = play_part(track,5,0.25,double=True)
track = play_part(track,2,0.25,double=True)
######## 第二段 ###########
track = play_part(track,3,0.5)
track = play_part(track,6,0.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)
track = play_part(track,6,0.5,-1)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,6,0.5,-1)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,5,1.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,3,0.25)
track = play_part(track,5,0.25)
track = play_part(track,5,1.5)
track = play_part(track,5,0.5,-1)
track = play_part(track,5,0.5,-1)
track = play_part(track,6,0.5,-1)
track = play_part(track,6,1.0,-1,change=True)
track = play_part(track,5,0.5,-1,double=True)
track = play_part(track,6,0.5,-1,double=True)
track = play_part(track,6,1.5,-1,double=True)
######## 剩下的請加油 XD ###########
mid.tracks.append(track)
mid.save('new_song.mid')
今天我們用 Python 實際編了一首曲子,其實體驗不是說很好,玩音樂的話果然還是要用一些專業的軟體比較好,但如果是要拿來做一些研究還是要從 python 出發,透過這次編曲也可以比較了解 MIDI 的運作>